package main

import (
	"fmt"
	"log"
	"net"
	"runtime"
	"time"
)

func catchErr(err error) {
	if err != nil {
		log.Fatalln(err)
	}
}

func main() {
	raddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:9999")
	catchErr(err)

	conn, err := net.DialTCP("tcp", nil, raddr)
	catchErr(err)
	fmt.Println(conn.LocalAddr())
	defer conn.Close()

	exit := make(chan struct{})

	go func() {
		buffer := make([]byte, 1024)
		for {
			conn.SetReadDeadline(time.Now().Add(time.Second))

			n, err := conn.Read(buffer)
			if err != nil {
				if _, ok := err.(*net.OpError); !ok {
					exit <- struct{}{}
					return
				}
				continue
			}
			fmt.Println(buffer[:n])
		}
	}()

	go func() {
		var input string
		for {
			fmt.Scanln(&input)
			if input == "exit" {
				exit <- struct{}{}
				return
			}
			_, err = conn.Write([]byte(input))
			if err != nil {
				log.Println(err)
				continue
			}
		}
	}()

	t := time.NewTicker(3 * time.Second)
	for {
		select {
		case <-exit:
			goto EXIT
		case <-t.C:
			fmt.Println(runtime.NumGoroutine(), "@@@")
		}
	}

EXIT:
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
}
